package com.huidatech.mpgdemo.crawler_unit;

import com.huidatech.mpgdemo.entity.Price;
import com.huidatech.mpgdemo.service.PriceService;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author wangzhuangzhuang
 * @DESC: 爬虫开发测试
 * @date 2021-10-19 13:28
 */

public class CrawlerForPriceUtils {

	// 构建站点源
	/**
	 * 	广东江门市新会区水果食品批发   https://price.21food.cn/market/580.html  分页规律  580-p2.html、580-p3.html、580-p4.html、580-p5 ......
	 * 	广东省广州市江南农副产品市场   https://price.21food.cn/market/746.html  分页规律  746-p2.html、746-p3.html、746-p4.html、746-p5 ......
	 * 	广东汕头农副产品批发中心       https://price.21food.cn/market/777.html  分页规律  777-p2.html、777-p3.html、777-p4.html、777-p5 ......
	 * 	广东江门市水产冻品副食批发市场 https://price.21food.cn/market/817.html  分页规律  817-p2.html、817-p3.html、817-p4.html、817-p5 ......
	 * 	佛山中南农产品交易中心		   https://price.21food.cn/market/847.html  分页规律  847-p2.html、847-p3.html、847-p4.html、847-p5 ......
	 * */
	/**
	 * 根据站点源构建属于该站点的URL种子列表
	 * */
    static List<String> getUrlSeeds(String url) throws Exception {
		// 构建站点列表
		List<String> urlSeeds = new ArrayList<String>();
		urlSeeds.add(url.trim());
		// 解析网页
		Document document = Jsoup.parse(new URL(url), 30000);
		// 得到总页数
		int totalPageSizeFromSource = getTotalPageSizeFromSource(document);
		// 拼接公共内容
		String prefixUrl = url.trim().substring(0, url.length() - 5);
		// 从第二页开始添加网页URL // 注释之后每次只爬取第一页
//		for(int i = 2; i < 3; i++){
//			String urlSeed = prefixUrl + "-p" + i + ".html";
//			urlSeeds.add(urlSeed.toString());
//		}
		return urlSeeds;
	}

	/**
     * 根据urlSeeds得到对应的urlDocuments
     * */
    static List<Document> getUrlDocuments(List<String> urlSeeds){
        List<Document> urlDocuments = new ArrayList<Document>();
	    urlSeeds.forEach(urlSeed -> {
            // 解析网页
            try {
                Document document = Jsoup.parse(new URL(urlSeed), 30000);
                urlDocuments.add(document);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
	    return urlDocuments;
    }

	/**
     * 得到总页数
     * */
	private static int getTotalPageSizeFromSource(Document document) {
		String totalPageSize = document.getElementsByClass("page").get(0).children().get(7).text(); // 得到一个站点需要爬取的总页数
		return Integer.valueOf(totalPageSize);
	}

    /**
     * 爬取单页所需内容
     * @param document 一个URL对应的Document
     * @param priceList 结果集
     * @return priceList
     */
	static void getResourceFromEachSource(Document document, List<Price> priceList) {
		Elements sjs_top_tv1 = document.getElementsByClass("sjs_top_tv1");
		// 获取所有的li元素
		Elements liElements = sjs_top_tv1.get(0).getElementsByTag("li");
		//System.out.println(liElements);
		liElements.forEach( li -> {
			// 得到li中的所有tbody
			Elements tbodyElements = li.getElementsByTag("tbody");
			tbodyElements.forEach(i -> {
				// 得到tbody中的tr
				Elements trElements = i.children();
				trElements.forEach(j -> {
					// 得到tr中的td列表
					Elements tdElements = j.children();
                    Price price = new Price();
                    price.setUpdateTime(new Date()); // 设置更新时间
					for(int m = 0; m < tdElements.size(); m++){
                        setPriceProperty(price, m, tdElements.get(m).text().trim());
                    }
					priceList.add(price);
				});
			});
		});
	}


    /**
     * 设置Price属性
     */
    private static Price setPriceProperty(Price price, int flag, String info) {
        String suffix = "元/公斤"; // 4
        switch (flag) {
            case 0:
                price.setProductName(info); // 产品名称
                break;
            case 1:
                price.setMarketName(info); // 报价市场
                break;
            case 2:
                double hightestPrice = Double.parseDouble(info.substring(0, info.length() - suffix.length()));
                price.setHighestPrice(hightestPrice); // 最高价
                break;
            case 3:
                double lowestPrice = Double.parseDouble(info.substring(0, info.length() - suffix.length()));
                price.setLowestPrice(lowestPrice); // 最低价
                break;
            case 4:
                // "平均价\t";
                break;
            case 5:
                price.setQuotationDate(info); // 报价日期
                break;
            case 6:
                // "走势图\t";
                break;
        }
        return price;
    }


	// ==============================================测试=======================================================



    @Autowired
    private static PriceService priceService;

    /**
     * 广东江门市新会区水果食品批发市场有限公司最新批发报价 https://price.21food.cn/market/580.html 至多爬取1页
     * 广东省广州市江南农副产品市场最新批发报价 https://price.21food.cn/market/746.html 至多爬取2页
     * 广东汕头农副产品批发中心最新批发报价 https://price.21food.cn/market/777.html 至少爬取3页
     * 广东江门市水产冻品副食批发市场最新批发报价 https://price.21food.cn/market/817.html 至多爬取2页
     * 佛山中南农产品交易中心最新批发报价 https://price.21food.cn/market/847.html 至多爬取1页
     * */

    public static void executeCrawlerProgram() throws Exception{
        // 获取请求站点源头
        String urlOriginalSeed = "https://price.21food.cn/market/847.html";
        // 获得URL种子
        List<String> urlSeeds = getUrlSeeds(urlOriginalSeed);
        // 获得URL种子对应文档对象
        List<Document> urlDocuments = getUrlDocuments(urlSeeds);
        // 结果集
        List<Price> priceList = new ArrayList<>();
        urlDocuments.forEach(document -> {
            getResourceFromEachSource(document, priceList);
        });
        priceList.forEach(price -> {
            priceService.save(price);
        });
        System.out.println("priceList's length: " + priceList.size());
    }

    public static void main(String[] args) throws Exception {
        executeCrawlerProgram();
    }
}






